package com.zb.service.imp.middleware;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.zb.dao.ext.charger.OmsChargerChargeBillRecordDao;
import com.zb.dao.ext.charger.OmsChargerDao;
import com.zb.dao.ext.charger.OmsChargerErrorRecordDao;
import com.zb.dao.ext.charger.OmsChargerStateAlternateDao;
import com.zb.dao.ext.charger.OmsChargerStateDirectDao;
import com.zb.dao.ext.dic.OmsPubParamDao;
import com.zb.entity.base.JsonCommon;
import com.zb.entity.charger.OmsCharger;
import com.zb.entity.charger.OmsChargerChargeBillRecord;
import com.zb.entity.charger.OmsChargerErrorRecord;
import com.zb.entity.charger.OmsChargerStateAlternate;
import com.zb.entity.charger.OmsChargerStateDirect;
import com.zb.entity.dic.OmsDicForwardSrvInfo;
import com.zb.entity.exception.BizException;
import com.zb.service.charger.OmsChargerErrorRecordService;
import com.zb.service.imp.middleware.notify.app.NotifyAppServer;
import com.zb.service.imp.sys.ChargeDataUploadingVO;
import com.zb.service.middleware.AnalysisService;
import com.zb.service.sys.BillService;
import com.zb.service.sys.ChargerChargeDirectRecordService;
import com.zb.service.sys.ChargerService;
import com.zb.service.sys.OmsDicForwardSrvInfoService;
import com.zb.tcp.rpc.as.SystemAppServerRpcClient;
import com.zb.tcp.rpc.as.client.constant.AppServerConstant;
import com.zb.tcp.rpc.as.client.entity.AppExceptionNotifyParam;
import com.zb.tcp.rpc.os.OrderRpcClient;
import com.zb.util.CardUtils;
import com.zb.util.OmsConstant;
import com.zb.util.RedisClient;
import com.zb.util.StringUtil;
import com.zb.util.OrderConstant.CardType;

import redis.clients.jedis.Jedis;
//本接口只做数据解析，不做数据接收  TODO dao 改 service 
//只用protocol_version
//chargerId:桩地址  port  source_ip source_port data  protocol_type  protocol_version 
@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class Ev3cAnalysisServiceImpl implements AnalysisService{
	private Log log = LogFactory.getLog(Ev3cAnalysisServiceImpl.class);
//	@Resource
//	RedisClient RedisClient;
//	@Resource
//	OmsChargerDao omsChargerDao;
	@Resource
	ChargerService chargerService;
//	@Resource
//	OmsChargerStateDirectDao omsChargerStateDirectDao;
//	@Resource
//	OmsChargerStateAlternateDao omsChargerStateAlternateDao;
//	@Resource
//	OmsChargerBespeakBillRecordDao omsChargerBespeakBillRecordDao;
	@Resource
	BillService billService;
//	@Resource
//	OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao;
	@Resource
	OmsPubParamDao omsPubParamDao;
//	@Resource
//	OmsChargerChargeDirectRecordDao omsChargerChargeDirectRecordDao;
	@Resource
	ChargerChargeDirectRecordService chargerChargeDirectRecordService;
//	@Resource
//	OrderRpcClient orderRpcClient;
//	@Resource
//	OmsDicForwardSrvInfoDao omsDicForwardSrvInfoDao;
	@Resource
	OmsDicForwardSrvInfoService omsDicForwardSrvInfoService;
	@Resource
	OmsChargerErrorRecordService omsChargerErrorRecordService;
	@Resource
	OmsChargerDao omsChargerDao;
	@Resource
	OmsChargerStateDirectDao omsChargerStateDirectDao;
	@Resource
	OmsChargerStateAlternateDao omsChargerStateAlternateDao;
	@Resource
	OmsChargerErrorRecordDao omsChargerErrorRecordDao;
//	@Resource
//	SystemAppServerRpcClient systemAppServerRpcClient;
	@Resource
	OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao;
	
	@Value(value="${omsFaultInformationUnit}")
	private String omsFaultInformationUnit;
	@Value(value="${omsFaultInformationConstant}")
	private String omsFaultInformationConstant;
	
	String ev3c_msg,ev3c_msgBody,ev3c_msgHeader,ev3c_frameCode,chargerId,protocol_version;
	@Override
	public Map<String, String> login(String str) {
		Map<String, String> map = StringUtil.ev3cString2JSONObject(str);
		String data = map.get("data");
		//报文体
		String fac_login_name = data.substring(50, 58); //注册账号  00005024  厂商表中检查
		String fac_password = data.substring(58, 66); //注册密码      21968502    
		String ev_fac_type1 = data.substring(66, 68); //设备一级类型  01      
		String ev_fac_type2 = data.substring(68, 70); //设备二级类型  00     
		String ev_sn = data.substring(70, 86); //设备SN  16位                          
		String ev_gps = data.substring(86, 102); //GPS坐标   16位   00..00
		map.put("fac_login_name", fac_login_name);
		map.put("fac_password", fac_password);
		map.put("ev_fac_type1", ev_fac_type1);
		map.put("ev_fac_type2", ev_fac_type2);
		map.put("ev_sn", ev_sn);
		map.put("ev_gps", ev_gps);
		return map;
	}

	@Override
	public Map<String, String> logout(String str) {
		Map<String, String> map= StringUtil.ev3cString2JSONObject(str);
		//报文体无
		return map;
	}

	@Override
	public Map<String, String> startChargeReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="56";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101StartChargeReturn(map);
				break;
			case "0102":
				map = ev3c0102StartChargeReturn(map);
				break;
			case "0103":
				map = ev3c0103StartChargeReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	@Override
	public Map<String, String> stopChargeReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="56";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101StopChargeReturn(map);
				break;
			case "0102":
				map = ev3c0102StopChargeReturn(map);
				break;
			case "0103":
				map = ev3c0103StopChargeReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	@SuppressWarnings("unused")
	private Map<String, String> ev3c0101StopChargeReturn(Map<String, String> map) {
		String chargerId,requestURL,responseMsgHeader,responseMsgBody,code,msg; 
		JsonCommon<String> json = new JsonCommon<String>();
		Date now = new Date();
		String data = map.get("data");
        String charge_port = data.substring(50, 52);
        charge_port = Ev3cEncapsulationServiceImpl.portNoWithDb(charge_port);
		String userCard = data.substring(54, 74);  //用户卡号
		map.put("charge_port", charge_port);
		map.put("userCard", userCard);
		return map;
	}
	@SuppressWarnings("unused")
	private Map<String, String> ev3c0102StopChargeReturn(Map<String, String> map) {
		String chargerId,requestURL,responseMsgHeader,responseMsgBody,code,msg; 
		JsonCommon<String> json = new JsonCommon<String>();
		Date now = new Date();
		String data = map.get("data");
        String charge_port = data.substring(50, 52);
        charge_port = Ev3cEncapsulationServiceImpl.portNoWithDb(charge_port);
		String userCard = data.substring(54, 74);  //用户卡号
		String chargeTime_min = data.substring(74, 78);  //累计充电时间（min）
		String soc_end = data.substring(78, 80);  //
		map.put("charge_port", charge_port);
		map.put("userCard", userCard);
		map.put("chargeTime_min", chargeTime_min);
		map.put("soc_end", soc_end);
		return map;
	}

	private Map<String,String> ev3c0103StopChargeReturn(Map<String, String> map) {
		return ev3c0102StopChargeReturn(map);
	}	
	
	
	
	@Override
	public Map<String, String> bespeakReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="15";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101BespeakReturn(map);
				break;
			case "0102":
				map = ev3c0102BespeakReturn(map);
				break;
			case "0103":
				map = ev3c0103BespeakReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101BespeakReturn(Map<String, String> map) {
		String data =  map.get("data");
		String port = data.substring(50, 52); // 充电口号 BIN码 1 00表示A口，01表示B口
												// 10表示C口···目前还没有C口
		port = Ev3cEncapsulationServiceImpl.portNoWithDb(port);
		String userCard = data.substring(52, 72); // 用户卡号
		map.put("port", port);
		map.put("userCard", userCard);
		return map;
	}

	private Map<String, String> ev3c0102BespeakReturn(Map<String, String> map) {
		 return ev3c0101BespeakReturn(map);
	}
	@SuppressWarnings("unused")
	private Map<String, String> ev3c0103BespeakReturn(Map<String, String> map) {
		JsonCommon<String> json = new JsonCommon<String>();
		String chargerId, requestURL, responseMsgHeader, responseMsgBody;
		// String[] header = StringUtil.getMessageHeader(data);
		// Map<String,String> headMap = StringUtil.getParameter(request);
		chargerId = map.get("chargerId");
		String data = map.get("data");
		String port = data.substring(50, 52); // 充电口号 BIN码 1 00表示A口，01表示B口
												// 10表示C口···目前还没有C口
		String userCard = data.substring(52, 72); // 用户卡号
		String startTime = data.substring(72, 86); // 预约开始时间 BCD码 7
													// 格式YYYY-MM-DD-hh-mm-ss
													// 例如：0x20 0x15 0x05 0x10
													// 0x13 0x20
													// 0x11,表示2015年5月10日13时20分11秒
		map.put("port", port);
		map.put("userCard", userCard);
		map.put("startTime", startTime);
		return map;
	}	
	
	
	@Override
	public Map<String, String> cancelBespeakReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="17";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101CancelBespeakReturn(map);
				break;
			case "0102":
				map = ev3c0102CancelBespeakReturn(map);
				break;
			case "0103":
				map = ev3c0103CancelBespeakReturn(map);
				break;
			default:
				break;
		}
		return map;
	}
	private Map<String, String> ev3c0101CancelBespeakReturn(Map<String, String> map) {
		String data = map.get("data");
		String port = data.substring(50, 52); // 充电口号 BIN码 1 00表示A口，01表示B口
												// 10表示C口···目前还没有C口
		port = Ev3cEncapsulationServiceImpl.portNoWithDb(port);
		String userCard = data.substring(52, 72); // 用户卡号
		map.put("port", port);
		map.put("userCard", userCard);
		
		// 如果是线下充值卡，就 1 数据库做记录，2  不传单价给订单服务器，调用订单接口 3 返回json
		if(userCard.startsWith("18806")){
			map.put("cardType", CardType.OFFLINE_CARD.value());
		}
		// 如果是线下卡（身份认证卡） ,则1 先查询数据库：  如果桩允许生成费用，则 2 数据库做记录；查询相关费率传总价给订单服务器，调用订单接口 3 返回json； 
		//如果桩不允许生成费用，则 查询单价 ，2 直接传总价给订单服务器，调用订单接口 ；数据库做记录3 返回json
		else if(userCard.startsWith("18805")){
			map.put("cardType", CardType.IDENTITY_CARD.value());
		}
		// 如果是线上卡app用户，,则1 先查询数据库：  如果桩允许生成费用，则 2 数据库做记录；查询相关费率传总价给订单服务器，调用订单接口 3 返回json； 
		//如果桩不允许生成费用，则 查询单价 ，2 直接传总价给订单服务器，调用订单接口 ；数据库做记录3 返回json
		else if(userCard.startsWith("18808")&&!userCard.substring(0, 9).equals("188089999")){
			map.put("cardType", CardType.ONLINE_CARD.value());
		}
		// 如果是线上卡企业用户，,则1 先查询数据库：  如果桩允许生成费用，则 2 数据库做记录；查询相关费率传总价给订单服务器，调用订单接口 3 返回json； 
		//如果桩不允许生成费用，则 查询单价 ，2 直接传总价给订单服务器，调用订单接口 ；数据库做记录3 返回json
		else if(userCard.startsWith("18808")){
			map.put("cardType", CardType.ONLINE_CARD.value());
		}
		return map;
	}

	private Map<String, String> ev3c0102CancelBespeakReturn(Map<String, String> map) {
		return ev3c0101CancelBespeakReturn(map);
	}
	private Map<String, String> ev3c0103CancelBespeakReturn(Map<String, String> map) {
		String data = map.get("data");
		String port = data.substring(50, 52); // 充电口号 BIN码 1 00表示A口，01表示B口
												// 10表示C口···目前还没有C口
		String userCard = data.substring(52, 72); // 用户卡号
		String startTime = data.substring(72, 86); // 预约开始时间 BCD码 7  1.3独有
		String endTime = data.substring(86, 100); // 
		map.put("port", port);
		map.put("userCard", userCard);
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		return map;
	}
	@Override
	public Map<String, String> restartChargerReturn(Map<String, String> map) {
		return map;
	}

	@Override
	public Map<String, String> updateFirmwareReturn(Map<String, String> map) {
		return map;
	}

	@Override
	public Map<String, String> findHardwareServerIpReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="31";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101FindHardwareServerIpReturn(map);
				break;
			case "0102":
				map = ev3c0101FindHardwareServerIpReturn(map);
				break;
			case "0103":
				map = ev3c0101FindHardwareServerIpReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101FindHardwareServerIpReturn(Map<String, String> map) {
		String data = map.get("data");
		chargerId = map.get("chargerId");
		String ipAdd1 = data.substring(50,58);  //
		String main_port = data.substring(58,62);  //
		String ipAdd2 = data.substring(62,70);  //
		String back_port = data.substring(70,74);  //
		String ipReal =StringUtil.sixteen2ip(ipAdd1);
		int portReal1 =(int)StringUtil.float16to10ByParamDesc(main_port, 1);
		String ipReal2 =StringUtil.sixteen2ip(ipAdd2);
		int portReal2 =(int)StringUtil.float16to10ByParamDesc(back_port, 1);
		map.put("main_hardware_ip", ipReal);
		map.put("main_port", String.valueOf(portReal1));
		map.put("back_headware_ip", ipReal2);
		map.put("back_port", String.valueOf(portReal2));
//		String main_hardware_ip = map.get("main_hardware_ip");//主硬件服务器ip
//		String main_hardware_ip_bin =  StringUtil.ip2HexStr(main_hardware_ip);
//		String main_port = map.get("main_port");//主硬件服务器端口
//		String main_port_bin =StringUtil.float10to16ByParamDesc(main_port, 1, 4);
//		String back_headware_ip = map.get("back_headware_ip");//备用硬件服务器ip
//		String back_headware_ip_bin =  StringUtil.ip2HexStr(back_headware_ip);
//		String back_port = map.get("back_port");///备用硬件服务器端口
//		String back_port_bin =StringUtil.float10to16ByParamDesc(back_port, 1, 4);
//		ev3c_msgBody =main_hardware_ip_bin + main_port_bin + back_headware_ip_bin + back_port_bin;
		return map;
	}

	@Override
	public Map<String, String> setHardwareServerIpReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="31";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101SetHardwareServerIpReturn(map);
				break;
			case "0102":
				map = ev3c0101SetHardwareServerIpReturn(map);
				break;
			case "0103":
				map = ev3c0101SetHardwareServerIpReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101SetHardwareServerIpReturn(Map<String, String> map) {
		protocol_version = map.get("protocol_version");
		String data = map.get("data");
		chargerId = map.get("chargerId");
		String effect_type = data.substring(50,52);  //生效类型  00：立即生效   01:延时生效：TODO 如果不是立即生效，则系统就不知道如何处理了
		int effect_type_int =  StringUtil.sixteen2tenInt(effect_type);//
		String effectDate = data.substring(52,66);  //生效时间 
		String ipAdd1 = data.substring(66,74);  //
		String main_port = data.substring(74,78);  //
		String ipAdd2 = data.substring(78,86);  //
		String back_port = data.substring(86,90);  //
		String ipReal =StringUtil.sixteen2ip(ipAdd1);
		int portReal1 =(int)StringUtil.float16to10ByParamDesc(main_port, 1);
		String ipReal2 =StringUtil.sixteen2ip(ipAdd2);
		int portReal2 =(int)StringUtil.float16to10ByParamDesc(back_port, 1);
		if(effect_type_int == 0){//query oms_dic_forward_srv_info[桩硬件服务器信息]  查询转发服务器编号 forward_srv_id ；update omscharger
			OmsDicForwardSrvInfo omsDicForwardSrvInfo_query = new OmsDicForwardSrvInfo();
			omsDicForwardSrvInfo_query.setMain_hardware_ip(ipReal);
			omsDicForwardSrvInfo_query.setMain_port_up(portReal1);
			omsDicForwardSrvInfo_query.setBack_headware_ip(ipReal2);
			omsDicForwardSrvInfo_query.setBack_port_up(portReal2);
			OmsDicForwardSrvInfo omsDicForwardSrvInfo = omsDicForwardSrvInfoService.findOneExample(omsDicForwardSrvInfo_query, null , null);
			if(omsDicForwardSrvInfo!=null){
				OmsCharger omsCharger_query = new OmsCharger();
				omsCharger_query.setCharger_id(chargerId);
				List<OmsCharger> omsCharger_list = chargerService.findExample(omsCharger_query, null, null, null, null);
				for(OmsCharger omsCharger :omsCharger_list){
					omsCharger.setForward_srv_id(omsDicForwardSrvInfo.getForward_srv_id());
					chargerService.update(omsCharger);
				}
			}
		}
		map.put("effect_type", String.valueOf(effect_type_int));
		map.put("effectDate", effectDate);
		map.put("main_hardware_ip", ipReal);
		map.put("main_port", String.valueOf(portReal1));
		map.put("back_headware_ip", ipReal2);
		map.put("back_port", String.valueOf(portReal2));
		return map;
	}

	@Override
	public Map<String, String> setTimeReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="35";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101SetTimeReturn(map);
				break;
			case "0102":
				map = ev3c0101SetTimeReturn(map);
				break;
			case "0103":
				map = ev3c0101SetTimeReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101SetTimeReturn(Map<String, String> map) {
		//如果桩上传的对时时间与桩差异太大，则存入日志或故障表中
		String data = map.get("data");
		if(data==null||data.length()!=64){
			return null;
		}
		String charger_time = data.substring(50, 64);
		Date charger_time_date = StringUtil.StrToDate(charger_time);
		Date now  = new Date();
		long seconds_long ;
		if(charger_time_date.getTime()>=now.getTime()){
			seconds_long = charger_time_date.getTime() - now.getTime();
		}else{
			seconds_long = now.getTime() - charger_time_date.getTime();
		}
		if(seconds_long<1000*60*10){//桩时间和服务器时间相差10分钟了就认为有问题10分钟
			//TODO 存入日志表
		}
		return map;
	}

	@Override
	public Map<String, String> findRateReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="37";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101FindRateReturn(map);
				break;
			case "0102":
				map = ev3c0101FindRateReturn(map);
				break;
			case "0103":
				map = ev3c0101FindRateReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101FindRateReturn(Map<String, String> map) {
//		String msgHeader, msgBody, code, msg, time;
		String data = map.get("data");
		String feeRate1 = data.substring(50,54); 
		String feeRate2 = data.substring(54,58);
		String feeRate3 = data.substring(58,62);
		String feeRate4 = data.substring(62,66);
		String server_fee = data.substring(66,70);
		String timeRate = data.substring(70,166);//
		//01010101...020202...030303...040404		
		
		int timeRate1 = timeRate.lastIndexOf("01");
		int  timeRate1_min = (timeRate1 + 2 )/2  * 30 ;
		int  timeRate1_hour = (timeRate1_min)/60 ;
		String timeRate1_end_time ="";
		if(timeRate1_min%60!=0){
			timeRate1_end_time = timeRate1_hour+":30:00";
		}else{
			timeRate1_end_time = timeRate1_hour+":00:00";
		}
		
		int timeRate2 = timeRate.lastIndexOf("02");
		int  timeRate2_min = (timeRate2 + 2 )/2  * 30 ;
		int  timeRate2_hour = (timeRate2_min)/60 ;
		String timeRate2_end_time ="";
		if(timeRate2_min%60!=0){
			timeRate2_end_time = timeRate2_hour+":30:00";
		}else{
			timeRate2_end_time = timeRate2_hour+":00:00";
		}
	
		int timeRate3 = timeRate.lastIndexOf("03");
		int  timeRate3_min = (timeRate3 + 2 )/2  * 30 ;
		int  timeRate3_hour = (timeRate3_min)/60 ;
		String timeRate3_end_time ="";
		if(timeRate3_min%60!=0){
			timeRate3_end_time = timeRate3_hour+":30:00";
		}else{
			timeRate3_end_time = timeRate3_hour+":00:00";
		}
		
		int timeRate4 = timeRate.lastIndexOf("04");
		int  timeRate4_min = (timeRate4 + 2 )/2  * 30 ;
		int  timeRate4_hour = (timeRate4_min)/60 ;
		String timeRate4_end_time ="";
		if(timeRate2_min%60!=0){
			timeRate4_end_time = timeRate4_hour+":30:00";
		}else{
			timeRate4_end_time = timeRate4_hour+":00:00";
		}
		map.put("rate1_start_time", "00:00:00");
		map.put("rate1_end_time", timeRate1_end_time);
		map.put("rate2_start_time", timeRate1_end_time);
		map.put("rate2_end_time", timeRate2_end_time);
		map.put("rate3_start_time", timeRate2_end_time);
		map.put("rate3_end_time",  timeRate3_end_time);
		map.put("rate4_start_time", timeRate3_end_time);
		map.put("rate4_end_time",  timeRate4_end_time);
		
//		//0xE8 0x03转化为10.00
		float feeRate1_float = StringUtil.float16to10ByParamDesc(feeRate1,100);
		float feeRate2_float = StringUtil.float16to10ByParamDesc(feeRate2,100);
		float feeRate3_float = StringUtil.float16to10ByParamDesc(feeRate3,100);
		float feeRate4_float = StringUtil.float16to10ByParamDesc(feeRate4,100);
		float server_fee_float = StringUtil.float16to10ByParamDesc(server_fee,100);
//		float timeRate_float = StringUtil.float16to10ByParamDesc(timeRate,1);
		map.put("feeRate1", String.valueOf(feeRate1_float));
		map.put("feeRate2", String.valueOf(feeRate2_float));
		map.put("feeRate3", String.valueOf(feeRate3_float));
		map.put("feeRate4", String.valueOf(feeRate4_float));
		map.put("server_fee", String.valueOf(server_fee_float));
//		map.put("timeRate", String.valueOf(timeRate_float));
		map.put("timeRate", timeRate);
		return map;
	}

	@Override
	public Map<String, String> setRateReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="39";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101SetRateReturn(map);
				break;
			case "0102":
				map = ev3c0101SetRateReturn(map);
				break;
			case "0103":
				map = ev3c0101SetRateReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101SetRateReturn(Map<String, String> map) {
//		String msgHeader, msgBody, code, msg, time;
		String data = map.get("data");
		String feeRate1 = data.substring(50,54); 
		String feeRate2 = data.substring(54,58);
		String feeRate3 = data.substring(58,62);
		String feeRate4 = data.substring(62,66);
		String server_fee = data.substring(66,70);
		String timeRate = data.substring(70,166);// 切成48段
		String[] timeRate_str = StringUtil.fortyeight2Threetime(timeRate);
		map.put("time1", timeRate_str[0]);
		map.put("time2", timeRate_str[1]);
		map.put("time3", timeRate_str[2]);
//		for(int i =0;i<timeRate.length();i=i+2){
//			String temp = timeRate.substring(i, i+2);
//		}
//		//0xE8 0x03转化为10.00
		float feeRate1_float = StringUtil.float16to10ByParamDesc(feeRate1,100);
		float feeRate2_float = StringUtil.float16to10ByParamDesc(feeRate2,100);
		float feeRate3_float = StringUtil.float16to10ByParamDesc(feeRate3,100);
		float feeRate4_float = StringUtil.float16to10ByParamDesc(feeRate4,100);
//		float server_fee_float = StringUtil.float16to10ByParamDesc(server_fee,100);
//		float timeRate_float = StringUtil.float16to10ByParamDesc(timeRate,1);
		map.put("feeRate1", String.valueOf(feeRate1_float));
		map.put("feeRate2", String.valueOf(feeRate2_float));
		map.put("feeRate3", String.valueOf(feeRate3_float));
		map.put("feeRate4", String.valueOf(feeRate4_float));
		map.put("server_fee", server_fee);
//		map.put("timeRate", String.valueOf(timeRate_float));
		return map;
	}

	@Override
	public Map<String, String> setQrCodeReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="78";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101SetQrCodeReturn(map);
				break;
			case "0102":
				map = ev3c0101SetQrCodeReturn(map);
				break;
			case "0103":
				map = ev3c0101SetQrCodeReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101SetQrCodeReturn(Map<String, String> map) {
		// TODO 插入数据库在另外的地方做
		String data = map.get("data");
//		String chargerId = map.get("chargerId");
		String qrCode = data.substring(50);
		map.put("qrCode", qrCode);
		return map;
	}

	@Override
	public Map<String, String> findWhiteListReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="3B";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				map = ev3c0103FindWhiteListReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0103FindWhiteListReturn(Map<String, String> map) {
		String data = map.get("data");
//		String chargerId = map.get("chargerId");
		String whiteList_bin = data.substring(50,52);
		String whiteList_no = StringUtil.sixteen2tenStr(whiteList_bin);
		String list_str = data.substring(52);
		StringBuilder sb = new StringBuilder("");//加逗号分隔
		if(StringUtil.isNotBlank(list_str)){
			for(int i=0;i<list_str.length();i=i+10){
				sb.append(list_str.substring(i, i+10)+",");
			}
			sb.deleteCharAt(sb.length() -1);
		}
		map.put("whiteList_no", whiteList_no);
		map.put("whiteList", sb.toString());
		return map;
	}

	@Override
	public Map<String, String> setWhiteListReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="3D";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				map = ev3c0103SetWhiteListReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0103SetWhiteListReturn(Map<String, String> map) {
		String data = map.get("data");
		String result = data.substring(50);
		map.put("result", result);
//		String chargerId = map.get("chargerId");
//		String whiteList_bin = data.substring(50,52);
//		String whiteList_no = StringUtil.sixteen2tenStr(whiteList_bin);
//		String list_str = data.substring(52);
//		StringBuilder sb = new StringBuilder("");//加逗号分隔
//		if(StringUtil.isNotBlank(list_str)){
//			for(int i=0;i<list_str.length();i=i+10){
//				sb.append(list_str.substring(i, i+10)+",");
//			}
//			sb.deleteCharAt(sb.length() -1);
//		}
//		map.put("whiteList_no", whiteList_no);
//		map.put("whiteList", sb.toString());
		return map;
	}

	@Override
	public Map<String, String> setParamReturn(Map<String, String> map) {
		//进一步解析  报文体
		ev3c_frameCode ="3F";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				map = ev3c0103SetParamReturn(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0103SetParamReturn(Map<String, String> map) {
		String data = map.get("data");
		String chargerId = map.get("chargerId");
		String result_type_bin = data.substring(50, 52);
		String param_no = data.substring(52, 54);
		String param_length = data.substring(54, 58);
		map.put("result_type_bin",result_type_bin);
		map.put("param_no",param_no);
		map.put("param_length",param_length);
		String param = "";
		float param_float = 0;
		String param_bin_desc = data.substring(58);
		switch(param_no){
			case "00":
				param_length = "0000";
				break;
			case "01":
			case "02":
			case "03":
				param_length = "0300";
				param_float = StringUtil.float16to10ByParamDesc(param_bin_desc, 100);
				param = String.valueOf(param_float);
				break;
			case "04":
				param_length = "0100";
				param_float = StringUtil.float16to10ByParamDesc(param_bin_desc, 1);
				param = String.valueOf(param_float);
				break;
			default:
				break;
		}
		map.put("param",param);
		String key = chargerId + "_param";
		StringUtil.removeNullValue(map);
		RedisClient.putMap(key, map);
		return map;
	}

	@Override
	public Map<String, String> requestPayByCard(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体
		ev3c_frameCode ="75";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101RequestPayByCard(map);
				break;
			case "0102":
				map = ev3c0101RequestPayByCard(map);
				break;
			case "0103":
				map = ev3c0101RequestPayByCard(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101RequestPayByCard(Map<String, String> map) {
		String data = map.get("data");
		String portNo = data.substring(50,52);
		portNo = Ev3cEncapsulationServiceImpl.portNoWithDb(map.get("portNo"));
		String userCard = data.substring(52);
		map.put("portNo", portNo);
		map.put("userCard", userCard);
		return map;
	}

	@Override
	public Map<String, String> uploadHeart(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体

		log.info(map);
		ev3c_frameCode ="75";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101UploadHeart(map);
				break;
			case "0102":
				map = ev3c0102UploadHeart(map);
				break;
			case "0103":
				map = ev3c0103UploadHeart(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101UploadHeart(Map<String, String> map) {
		Jedis jedis = RedisClient.getConnect();
		try {	
			//心跳存入redis
			String data = map.get("data");
			String chargerId = map.get("chargerId");
	//		String serialNumber = map.get("serialNumber");
	//		String key = chargerId +"_heart_"+serialNumber;
	
			String charger_kwh = data.substring(54, 62);
			String key_status = chargerId+ "01"+"_status";
	
			//jedis.set(key, data);
			//jedis.expire(key, 60 * 60 * 24 * 7);
	
			String json = jedis.get(key_status);
			ChargeDataUploadingVO vo = null;
			if(json == null)
			{
				vo = new ChargeDataUploadingVO();
			}
			else
			{
				vo = JSON.parseObject(json, ChargeDataUploadingVO.class);
			}
			vo.setCharger_kwh(charger_kwh);
			json = JSON.toJSONString(vo);
			jedis.set(key_status, json);
	
			String codeError = data.substring(74, 76); //故障代码         
			map.put("codeError", codeError);// TODO 另外 的地方  如果不为00 00 00，，
			//则需要存入故障表中。如果故障表中已经有记录，就不用反复存入（一天存一条）。
			
		} finally {
			jedis.close();
		}
		return map;
	}

	private Map<String, String> ev3c0102UploadHeart(Map<String, String> map) {
		Jedis jedis = RedisClient.getConnect();
		try {
		    // 心跳存入redis
			String data = map.get("data");
			String chargerId = map.get("chargerId");
			String serialNumber = map.get("serialNumber");
			String key = chargerId +"_heart_"+serialNumber;
			//edit by chenjie:取消此心跳数据data的缓存
			//jedis.set(key, data);
			//jedis.expire(key, 60 * 60 * 24 * 7);
	
			String chargerPort = data.substring(52, 53);
			String curChargeStatus = data.substring(53, 54); // 充电桩状态
			float chargerKwh = StringUtil.float16to10ByParamDesc(data.substring(54,62), 100); //本次充电电量
			float chargerFee = StringUtil.float16to10ByParamDesc(data.substring(62,70), 100);  //本次充电金额
			float chargerV = StringUtil.float16to10ByParamDesc(data.substring(76,82), 100);  //电压
			float chargerI = StringUtil.float16to10ByParamDesc(data.substring(82,88), 100);  //电流
			float chargerMinute = StringUtil.int16to10ByParamDesc(data.substring(88,94));  //充电时间(分)
			float chargerP = (int)StringUtil.int16to10ByParamDesc(data.substring(94,100));  //输出功率(W)	
			//int cableStatus = Integer.valueOf(data.substring(100, 102)); //充电接口状态
			int chargerSoc = 0;
			String soc = data.substring(102,104);
			if (soc != null && !soc.equals("FF")) { // FF:无效
				chargerSoc = (int)StringUtil.int16to10ByParamDesc(soc);  //当前荷电状态SOC(%)
			}
			int remainingTime = 0;
			String remainingTimeLen = data.substring(104,108);
			if (remainingTimeLen != null && !remainingTimeLen.equals("FFFF")) { // FFFF:无效
				remainingTime = (int)StringUtil.int16to10ByParamDesc(remainingTimeLen);  //估算剩余充电时间
			}	
			String codeError = data.substring(108, 116); //详细故障代码         
			map.put("codeError", codeError);// TODO 另外 的地方  如果不为00 00 00 00,1.2文档中有误。
			
			int port_no = Integer.valueOf(chargerPort) + 1; // 数据库中是从0开始,报文是从0开始
			String chargeStatus = "0"; // 0:空闲, 1:充电, 2:预约
			switch (curChargeStatus) {
			case "1": // 充电
				chargeStatus = "2";
				break;
			case "2": // 预约
				chargeStatus = "1";
				break;
			default:
				chargeStatus = "0";
				break;
			}
			
			OmsCharger charger_query = new OmsCharger();
			charger_query.setCharger_id(chargerId);
			charger_query.setPort_no(port_no); // 枪口号:下发到桩从0开始,数据库从1开始
			OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
			if (codeError.equals("00000000")) { // 非故障
				// 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
				if (charger.getCharger_type() != null) {
					int chargerType = charger.getCharger_type();
					switch (chargerType) { // 1:直流  2:交流  3:混合
					case 1:
						OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
						directState_query.setPort_no(port_no);
						directState_query.setCharger_id(chargerId);
						OmsChargerStateDirect directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query, null, null);
						if (directState.getCharge_status().intValue() != Integer.valueOf(chargeStatus)) {
							directState.setCharge_status(Integer.valueOf(chargeStatus)); // 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
							omsChargerStateDirectDao.updateObject(directState);
						}
						break;
					case 2:
						OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
						alternateState_query.setPort_no(port_no);
						alternateState_query.setCharger_id(chargerId);
						OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
						if (alternateState.getCharge_status().intValue() != Integer.valueOf(chargeStatus)) {
							alternateState.setCharge_status(Integer.valueOf(chargeStatus)); // 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
							omsChargerStateAlternateDao.updateObject(alternateState);
						}
						break;
					default:
						break;
					}
				}
			} else { // 入库oms_charger_error_record[故障记录表]
				// 1分钟以内上报同一故障信息,不做入库处理
				String unit = "ss"; // 小时:HH, 分钟:mm, 秒:ss
				unit = omsFaultInformationUnit;
				long base = 1; // 基数
				int constant = 1; // 常量
				constant = Integer.valueOf(omsFaultInformationConstant);
				StringBuffer sql = new StringBuffer();
				switch (unit) {
				case "hh":
					base = 60 * 60;
					break;
				case "mm": // 分钟
					base = 60;
					break;
				case "ss": // 秒
					base = 1;
					break;
				default:
					base = 1;
					break;
				}
				sql.append("select COUNT(create_time) as total from oms_charger_error_record WHERE charger_id = '"
						+ chargerId + "'" + " and error_code = '" + codeError + "'" + " and status = 0"
						+ " and valid_flag = 1" + " and (UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(create_time)) / " + base
						+ " < " + constant);
				List<Map<String, Object>> chargerList = new ArrayList<Map<String, Object>>();
				chargerList = omsChargerErrorRecordDao.findDataBySql(sql.toString());
				String total = chargerList.get(0).get("total").toString();
				if (total.equals("0")) { // 1分钟内没有重复故障数据,做入库处理
					OmsChargerErrorRecord record = new OmsChargerErrorRecord();
					record.setCharger_id(chargerId);
					record.setError_code(codeError);
					record.setError_msg("ev3c0102UploadHeart fault!");
					record.setStatus(0); // 0:未处理,1:已处理
					record.setValid_flag(1);
					record.setCreate_oper_id("000");
					record.setCreate_time(new Date());
					omsChargerErrorRecordService.add(record);
				}
				
				String userCard = "";
				// 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
				if (charger.getCharger_type() != null) {
					int chargerType = charger.getCharger_type();
					switch (chargerType) { // 1:直流  2:交流  3:混合
					case 1:
						OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
						directState_query.setPort_no(port_no);
						directState_query.setCharger_id(chargerId);
						OmsChargerStateDirect directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query, null, null);
						userCard = directState.getUser_pay_card();
						directState.setCharge_status(3); // 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
						directState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
						directState.setUser_pay_card("");
						omsChargerStateDirectDao.updateObject(directState);
						break;
					case 2:
						OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
						alternateState_query.setPort_no(port_no);
						alternateState_query.setCharger_id(chargerId);
						OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
						userCard = alternateState.getUser_pay_card();
						alternateState.setCharge_status(3); // 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
						alternateState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
						alternateState.setUser_pay_card("");
						omsChargerStateAlternateDao.updateObject(alternateState);
						break;
					default:
						break;
					}
				}
				
				// 发送异常推送消息
				if (userCard != null && !userCard.equals("null") && !userCard.equals("")) { // 发送推送消息到用户
					OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
					OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
					billRecord_query.setCharger_id(chargerId);
					billRecord_query.setStation_id(charger.getStation_id());
					// billRecord_query.setStatus(4); // 由于自动充满导致没有更新该状态
					billRecord_query.setPort_no(port_no);
					billRecord_query.setValid_flag(1);
					billRecord_query.setUser_pay_card(userCard);
					billRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query,"start_time","desc");
					try {
						NotifyAppServer.exceptionNotify(AppServerConstant.EXCEPTION_NOTIFY_ACTION_END_CHARGE, billRecord.getMsg_charge_jrnl(), billRecord.getCharger_id(), codeError);
					} catch (BizException e) {
						log.error("发送推送消息到用户失败!");
					}
				}
			}
			
			String key_charging = chargerId + "01" + "_status";
			String json = jedis.get(key_charging);
			ChargeDataUploadingVO vo = null;
			if(json == null)
			{
				vo = new ChargeDataUploadingVO();
			}
			else
			{
				vo = JSON.parseObject(json, ChargeDataUploadingVO.class);
			}
			vo.setCharger_kwh(String.valueOf(chargerKwh));
			vo.setCharger_time(String.valueOf(chargerMinute));
			vo.setCharger_fee(String.valueOf(chargerFee));
			vo.setCharger_v(String.valueOf(chargerV));
			vo.setCharger_i(String.valueOf(chargerI));
			vo.setCharger_p(String.valueOf(chargerP));
			vo.setSoc(Integer.toString(chargerSoc));
			vo.setRemaining_time(Integer.toString(remainingTime));
			
			json = JSON.toJSONString(vo);
			if (Integer.valueOf(curChargeStatus) == 1) { // chargeStatus:0:空闲 1:充电 2:预约;如果电桩状态是充电中,则写入redis
				jedis.set(key_charging, json);
			}
		
		} finally {
			jedis.close();
		}	
		return map;
	}

	private Map<String, String> ev3c0103UploadHeart(Map<String, String> map) {
		log.info(map);
		//心跳存入redis
		String data = map.get("data");
		String chargerId = map.get("chargerId");
		String serialNumber = map.get("serialNumber");
		String key = chargerId +"_heart_"+serialNumber;
		RedisClient.putString(key, data);
		RedisClient.expire(key, 60*60*24*7);//7天
		//则需要存入故障表中。如果故障表中已经有记录，就不用反复存入（一天存一条）。
		return map;
	}

	@Override
	public Map<String, String> uploadChange(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体  1.2 没有主动遥变
		ev3c_frameCode ="75";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101UploadChange(map);
				break;
			case "0103":
				map = ev3c0103UploadChange(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101UploadChange(Map<String, String> map) {
		String data = map.get("data");
		String status_type = data.substring(50, 52);
		String status_value = data.substring(52);
		map.put("status_type", status_type);
		map.put("status_value", status_value);
		return map;
	}

	private Map<String, String> ev3c0103UploadChange(Map<String, String> map) {
		String data = map.get("data");
		String status_type = data.substring(50, 52);
		String status_value = data.substring(52);
		map.put("status_type", status_type);
		map.put("status_value", status_value);
		return map;
	}

	@Override
	public Map<String, String> uploadFirmwareStatus(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体  1.2 没有主动遥变
		ev3c_frameCode ="75";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				map = ev3c0103UploadFirmwareStatus(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0103UploadFirmwareStatus(Map<String, String> map) {
		// TODO oms_charger_software_refresh[桩固件更新记录]
		String data = map.get("data");
		//00：升级完成（初始状态值）
		//		01：下载中
		//		02：下载完成
		//		03：开始安装
		//		FF：升级失败
		String status = data.substring(50, 52);
		if(data.length()>=60){
			String additional_data = data.substring(52, 60);
			map.put("additional_data", additional_data);
		}
		map.put("status", status);
		
		return map;
	}

	@Override
	public Map<String, String> uploadBill(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体  
		ev3c_frameCode ="54";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101UploadBill(map);
				break;
			case "0102":
				map = ev3c0101UploadBill(map);
				break;
			case "0103":
				map = ev3c0103UploadBill(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101UploadBill(Map<String, String> map) {
		try {
			String data = map.get("data");
			String start_time =data.substring(50, 64);
			start_time =  StringUtil.time14format(start_time);
			long start_time_long = new java.text.SimpleDateFormat ("yyyyMMddHHmmss").parse(start_time).getTime();
			String end_time =data.substring(64, 78);
			end_time =  StringUtil.time14format(end_time);
			long end_time_long = new java.text.SimpleDateFormat ("yyyyMMddHHmmss").parse(end_time).getTime();
			long charge_time = end_time_long - start_time_long;
			String userCard =data.substring(78, 98);
			float start_em = StringUtil.float16to10ByParamDesc(data.substring(98,106), 1); //*充电前电表读数 BIN码 4 系数为0.01 低字节在前，高字节在后，实际值X100上送
			float end_em = StringUtil.float16to10ByParamDesc(data.substring(106,114), 1); //*充电后电表读数 BIN码 4 系数为0.01 低字节在前，高字节在后，实际值X100上送
			float this_reading = StringUtil.float16to10ByParamDesc(data.substring(114,122), 1);//*本次充电电量  与上类似
			float this_amount = StringUtil.float16to10ByParamDesc(data.substring(122,130), 1);//*本次充电金额  与上类似
			float offline_balance_start = StringUtil.float16to10ByParamDesc(data.substring(130,138), 1);//充电前卡余额  与上类似
			float offline_balance_end = StringUtil.float16to10ByParamDesc(data.substring(138,146), 1);//充电后卡余额  与上类似
			float char_bill_id = StringUtil.float16to10ByParamDesc(data.substring(146,150), 1);//服务费金额  2   与上类似
			String offline_is_pay =data.substring(150, 152);
			int offline_is_pay_int = Integer.valueOf(offline_is_pay);
			map.put("start_time", start_time);
			map.put("end_time", end_time);
			map.put("charge_time_min", String.valueOf(charge_time/(1000*60)));
			map.put("userCard", userCard);
			map.put("start_em", String.valueOf(start_em));
			map.put("end_em", String.valueOf(end_em));
			map.put("this_reading",String.valueOf(this_reading));
			map.put("this_amount", String.valueOf(this_amount));
			map.put("offline_balance_start", String.valueOf(offline_balance_start));
			map.put("offline_balance_end", String.valueOf(offline_balance_end));
			map.put("char_bill_id", String.valueOf(char_bill_id));
			map.put("offline_is_pay", String.valueOf(offline_is_pay_int));
		} catch (NumberFormatException e) {
			map.put("oms_error_code", "10303202");
			map.put("oms_error_msg", e.getMessage());
			e.printStackTrace();
		} catch (ParseException e) {
			map.put("oms_error_code", "10303202");
			map.put("oms_error_msg", e.getMessage());
			e.printStackTrace();
		} catch (Exception e) {
			map.put("oms_error_code", "10303200");
			map.put("oms_error_msg", e.getMessage());
			e.printStackTrace();
		}
		return map;
	}

	private Map<String, String> ev3c0103UploadBill(Map<String, String> map) {
		try {
			String data = map.get("data");
			String start_time =data.substring(50, 64);
//			start_time =  StringUtil.time14format(start_time);
			long start_time_long = new java.text.SimpleDateFormat ("yyyyMMddHHmmss").parse(start_time).getTime();
			String end_time =data.substring(64, 78);
//			end_time =  StringUtil.time14format(end_time);
			long end_time_long = new java.text.SimpleDateFormat ("yyyyMMddHHmmss").parse(end_time).getTime();
			long charge_time = end_time_long - start_time_long;
			String userCard =data.substring(78, 98);
			float start_em = StringUtil.float16to10ByParamDesc(data.substring(98,106), 100); //*充电前电表读数 BIN码 4 系数为0.01 低字节在前，高字节在后，实际值X100上送
			float end_em = StringUtil.float16to10ByParamDesc(data.substring(106,114), 100); //*充电后电表读数 BIN码 4 系数为0.01 低字节在前，高字节在后，实际值X100上送
			float this_reading = StringUtil.float16to10ByParamDesc(data.substring(114,122), 100);//*本次充电电量  与上类似
			float this_amount = StringUtil.float16to10ByParamDesc(data.substring(122,130), 100);//*本次充电金额  与上类似
			float offline_balance_start = StringUtil.float16to10ByParamDesc(data.substring(130,138), 100);//充电前卡余额  与上类似
			float offline_balance_end = StringUtil.float16to10ByParamDesc(data.substring(138,146), 100);//充电后卡余额  与上类似
			float char_bill_id = StringUtil.float16to10ByParamDesc(data.substring(146,150), 100);//服务费金额  2   与上类似
			String org_serial_no = data.substring(150,164);//原流水号,开启充电时的流水号，通过该流水号绑定账单与开启充电的关系，流水号定义参见报文头
			map.put("org_serial_no", org_serial_no);
			String offline_is_pay =data.substring(164, 166);
			int offline_is_pay_int = Integer.valueOf(offline_is_pay);
			map.put("start_time", start_time);
			map.put("end_time", end_time);
			map.put("charge_time_min", String.valueOf(charge_time/(1000*60)));
			map.put("userCard", userCard);
			map.put("start_em", String.valueOf(start_em));
			map.put("end_em", String.valueOf(end_em));
			map.put("this_reading",String.valueOf(this_reading));
			map.put("this_amount", String.valueOf(this_amount));
			map.put("offline_balance_start", String.valueOf(offline_balance_start));
			map.put("offline_balance_end", String.valueOf(offline_balance_end));
			map.put("char_bill_id", String.valueOf(char_bill_id));
			map.put("offline_is_pay", String.valueOf(offline_is_pay_int));
			//1.3
			String charge_end_reason =data.substring(166, 168);//充电结束原因
//			0x01: 后台远程控制正常结束
//			0x02: 本地刷卡控制正常结束
//			0x03: 满足预设停止条件正常结束
//			0x04：电池满电正常结束
			String charge_start_mode = data.substring(168, 170);//充电启动方式 0x00：后台远程启动 0x01: 本地刷卡远程验证启动  0x02：本地刷卡白名单验证启动
			String control_type = data.substring(170, 172);//控制类型  参考控制类型表对应数据，如0x04为自动充满方式。
			String open_restricted_data = data.substring(172, 180);//开启限制数据  自动充满停机方式下无意义。低字节在前，高字节在后。电量控制,单位为“度”，精确到0.01,传输数据放大100倍；时间控制，单位为“秒“，精确到1,；金额控制，单位为“元”，精确到0.01，传输数据放大100倍。
			float open_restricted_data_float = 0;
			String control_type_stop_condition = control_type.substring(1, 2);
			switch(control_type_stop_condition){
				case "1"://电量控制充电  电量控制,单位为“度”，精确到0.01,传输数据放大100倍；
					open_restricted_data_float = StringUtil.float16to10ByParamDesc(open_restricted_data, 100);
					break;
				case "2"://时间控制充电 时间控制，单位为“秒“，精确到1,
					open_restricted_data_float = StringUtil.float16to10ByParamDesc(open_restricted_data, 1);
					break;
				case "3"://金额控制充电  金额控制，单位为“元”，精确到0.01，传输数据放大100倍。
					open_restricted_data_float = StringUtil.float16to10ByParamDesc(open_restricted_data, 100);
					break;
				case "4"://自动充满为止
					break;
				default:
					break;
			}
			String vehicle_identification_code = data.substring(180, 214);//车辆识别码
			map.put("charge_start_mode", charge_start_mode);
			map.put("charge_end_reason", charge_end_reason);
			map.put("control_type", control_type);
			map.put("open_restricted_data", String.valueOf(open_restricted_data_float));
			map.put("vin", vehicle_identification_code);
		} catch (NumberFormatException e) {
			map.put("oms_error_code", "10303202");
			map.put("oms_error_msg", e.getMessage());
			e.printStackTrace();
		} catch (ParseException e) {
			map.put("oms_error_code", "10303202");
			map.put("oms_error_msg", e.getMessage());
			e.printStackTrace();
		} catch (Exception e) {
			map.put("oms_error_code", "10303200");
			map.put("oms_error_msg", e.getMessage());
			e.printStackTrace();
		}
		return map;
	}

	@Override
	public Map<String, String> uploadChargeData(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体  
		ev3c_frameCode ="5C";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				map = ev3c0103UploadChargeData(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0103UploadChargeData(Map<String, String> map) {
		//存入redis中，时间为7天
		String data = map.get("data");
		String chargerId = map.get("chargerId");
		String serialNumber =map.get("serialNumber");
		Map<String, String> hashMap = new HashMap<String, String>();
		hashMap.put("msg_header", data.substring(0,50));
		String reading_time = data.substring(50, 64);
		hashMap.put("reading_time", reading_time);
		String port_no = data.substring(64, 66);
		hashMap.put("port_no", port_no);
		String ammeter_beforeCharge = data.substring(66, 74);
		hashMap.put("ammeter_beforeCharge", StringUtil.str16to10ByParamDesc(ammeter_beforeCharge, 100));
		String ammeter_now = data.substring(74, 82);
		hashMap.put("ammeter_now", StringUtil.str16to10ByParamDesc(ammeter_now, 100));
		String charge_money = data.substring(82, 90);
		hashMap.put("charge_money", StringUtil.str16to10ByParamDesc(charge_money, 100));
		String charge_v = data.substring(90, 96);
		hashMap.put("charge_v", StringUtil.str16to10ByParamDesc(charge_v, 100));
		String charge_a = data.substring(96, 102);
		hashMap.put("charge_a", StringUtil.str16to10ByParamDesc(charge_a, 100));
		String charge_min = data.substring(102, 108);
		hashMap.put("charge_min", StringUtil.str16to10ByParamDesc(charge_min, 1));
		String charge_w = data.substring(108, 114);
		hashMap.put("charge_w", StringUtil.str16to10ByParamDesc(charge_w, 1));
		String status_port = data.substring(114, 116);
		hashMap.put("status_port", StringUtil.str16to10ByParamDesc(status_port, 1));
		String status_soc = data.substring(116, 118);
		hashMap.put("status_soc", StringUtil.str16to10ByParamDesc(status_soc, 1));
		String estimated_remaining_charging_time = data.substring(118, 122);
		hashMap.put("estimated_remaining_charging_time", StringUtil.str16to10ByParamDesc(estimated_remaining_charging_time, 1));
		String voltage_and_number = data.substring(122, 126);
		hashMap.put("voltage_and_number", voltage_and_number);
		String key =chargerId+"_"+port_no+"_uploadChargeData_"+serialNumber;
		RedisClient.putMap(key, hashMap);
		RedisClient.expire(key, 60*60*24*7);
		return hashMap;
	}

	@Override
	public Map<String, String> uploadBatteryData(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体  
		ev3c_frameCode ="5D";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				map = ev3c0103UploadBatteryData(map);
				break;
			default:
				break;
		}
		return map;
	}
	private Map<String, String> ev3c0103UploadBatteryData(Map<String, String> map) {
		//存入redis中，时间为7天
		String data = map.get("data");
		String chargerId = map.get("chargerId");
		String serialNumber =map.get("serialNumber");
		Map<String, String> hashMap = new HashMap<String, String>();
		hashMap.put("msg_header", data.substring(0,50));
		hashMap.put("msg_body", data.substring(50));
		//TODO 解析报文
//		String reading_time = data.substring(50, 64);
//		hashMap.put("reading_time", reading_time);
//		String port_no = data.substring(64, 68);
//		hashMap.put("port_no", port_no);
//		String ammeter_beforeCharge = data.substring(68, 76);
//		hashMap.put("ammeter_beforeCharge", StringUtil.str16to10ByParamDesc(ammeter_beforeCharge, 100));
//		String ammeter_now = data.substring(76, 84);
//		hashMap.put("ammeter_now", StringUtil.str16to10ByParamDesc(ammeter_now, 100));
//		String charge_money = data.substring(84, 92);
//		hashMap.put("charge_money", StringUtil.str16to10ByParamDesc(charge_money, 100));
//		String charge_v = data.substring(92, 98);
//		hashMap.put("charge_v", StringUtil.str16to10ByParamDesc(charge_v, 100));
//		String charge_a = data.substring(98, 104);
//		hashMap.put("charge_a", StringUtil.str16to10ByParamDesc(charge_a, 100));
//		String charge_min = data.substring(104, 110);
//		hashMap.put("charge_min", StringUtil.str16to10ByParamDesc(charge_min, 1));
//		String charge_w = data.substring(110, 116);
//		hashMap.put("charge_w", StringUtil.str16to10ByParamDesc(charge_w, 1));
//		String status_port = data.substring(116, 118);
//		hashMap.put("status_port", StringUtil.str16to10ByParamDesc(status_port, 1));
//		String status_soc = data.substring(118, 120);
//		hashMap.put("status_soc", StringUtil.str16to10ByParamDesc(status_soc, 1));
//		String estimated_remaining_charging_time = data.substring(120, 124);
//		hashMap.put("estimated_remaining_charging_time", StringUtil.str16to10ByParamDesc(estimated_remaining_charging_time, 1));
//		String voltage_and_number = data.substring(124, 128);
//		String voltage_bin =  voltage_and_number.substring(0, 12);
//		String voltage = StringUtil.str16to10ByParamDesc(voltage_bin, 1);
//		String voltage_number_bin =  voltage_and_number.substring(12);
//		String voltage_number = StringUtil.str16to10ByParamDesc(voltage_number_bin, 1);
////		hashMap.put("voltage_and_number", voltage_and_number);
//		hashMap.put("voltage", voltage);
//		hashMap.put("voltage_number", voltage_number);
		String key =chargerId+"_uploadBatteryData_"+serialNumber;
		RedisClient.putMap(key, hashMap);
		RedisClient.expire(key, 60*60*24*7);
		return hashMap;
	}

	@SuppressWarnings("unused")
	private Map<String, String> ev3c0101StartChargeReturn(Map<String, String> map) {
//		String data = map.get("data");
//		JsonCommon<String> json = new JsonCommon<String>();
////		String[] header = StringUtil.getMessageHeader(data);
//		String charge_port = data.substring(50, 52);  //充电口号
//		charge_port = Ev3cEncapsulationServiceImpl.portNoWithDb(charge_port);
//		map.put("charge_port", charge_port);
//		int port_no = Integer.parseInt(charge_port, 2);
//		String userCard = data.substring(70, 90);  //用户卡号
//		map.put("userCard", userCard);
//		return map;


		//兼容1.1
		String chargerId,bespeakJrnl,responseMsgHeader,responseMsgBody,requestURL;
		String data = map.get("data");
		JsonCommon<String> json = new JsonCommon<String>();
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
		chargerId = map.get("chargerId");
		Date now = new Date();
		OmsChargerStateDirect directState;
		OmsChargerStateAlternate alternateState;
		String charge_port = data.substring(50, 52);  //充电口号
		charge_port = Ev3cEncapsulationServiceImpl.portNoWithDb(charge_port);
		String userCard = data.substring(70, 90);  //用户卡号
		String vin = data.substring(90, 124);  //车辆识别码（VIN） 可选填（0xff为无效）
		//查询桩是否被预约，如果没有预约，就不需要做关联。
		String battery_type = "0101";//data.substring(124, 126);  //
		String battery_fac = "0101";//data.substring(126, 134);  //
		//134-142  电池组序号 不存入数据库
		String battery_volume = "0101";//data.substring(142, 146);  //
		String battery_charge_times = "0101";//data.substring(146, 152);  //
		String soc = "0101";//data.substring(152, 154);  //
		map.put("charge_port", charge_port);
		map.put("userCard", userCard);
		map.put("vin", vin);
		map.put("battery_type", battery_type);
		map.put("battery_fac", battery_fac);
		map.put("battery_volume", battery_volume);
		map.put("battery_charge_times", battery_charge_times);
		map.put("soc", soc);
		return map;

	}
	@SuppressWarnings("unused")
	private Map<String, String> ev3c0102StartChargeReturn(Map<String, String> map) {
		String chargerId,bespeakJrnl,responseMsgHeader,responseMsgBody,requestURL; 
		String data = map.get("data");
		JsonCommon<String> json = new JsonCommon<String>();
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
		chargerId = map.get("chargerId");
		Date now = new Date();
		OmsChargerStateDirect directState;
		OmsChargerStateAlternate alternateState;
		String charge_port = data.substring(50, 52);  //充电口号
		charge_port = Ev3cEncapsulationServiceImpl.portNoWithDb(charge_port);
		String userCard = data.substring(70, 90);  //用户卡号
		String vin = data.substring(90, 124);  //车辆识别码（VIN） 可选填（0xff为无效）
		//查询桩是否被预约，如果没有预约，就不需要做关联。
		String battery_type = data.substring(124, 126);  //
		String battery_fac = data.substring(126, 134);  //
		//134-142  电池组序号 不存入数据库
		String battery_volume = data.substring(142, 146);  //
		String battery_charge_times = data.substring(146, 152);  //
		String soc = data.substring(152, 154);  //
		map.put("charge_port", charge_port);
		map.put("userCard", userCard);
		map.put("vin", vin);
		map.put("battery_type", battery_type);
		map.put("battery_fac", battery_fac);
		map.put("battery_volume", battery_volume);
		map.put("battery_charge_times", battery_charge_times);
		map.put("soc", soc);
        return map;
	}
	@SuppressWarnings("unused")
	private Map<String, String> ev3c0103StartChargeReturn(Map<String, String> map) {
		String chargerId,bespeakJrnl,responseMsgHeader,responseMsgBody,requestURL; 
		String data = map.get("data");
		JsonCommon<String> json = new JsonCommon<String>();
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
//		String[] header = StringUtil.getMessageHeader(data); 
		chargerId = map.get("chargerId");
		Date now = new Date();
		OmsChargerStateDirect directState;
		OmsChargerStateAlternate alternateState;
		String charge_port = data.substring(50, 52);  //充电口号
		String userCard = data.substring(70, 90);  //用户卡号
		String vin = data.substring(90, 124);  //车辆识别码（VIN） 可选填（0xff为无效）
//		//查询桩是否被预约，如果没有预约，就不需要做关联。
		String battery_type = data.substring(124, 126);  //
		String battery_fac = data.substring(126, 134);  //
		String battery_volume = data.substring(134, 138);  //
		String battery_voltage = data.substring(138, 142);  //
		String battery_charge_times = data.substring(142, 148);  //
		String battery_voltage_max = data.substring(148, 152);  //
		String battery_current_max = data.substring(152, 156);  //
		String battery_energy_total = data.substring(156, 160);  //
		String voltage_max = data.substring(160, 164);  //
		String battery_temperature_max = data.substring(164, 166);  //
		String soc = data.substring(166, 170);  //
		String battery_voltage_total = data.substring(170, 174);  //
		map.put("charge_port", charge_port);
		map.put("userCard", userCard);
		map.put("vin", vin);
		map.put("battery_type", battery_type);
		map.put("battery_fac", battery_fac);
		map.put("battery_volume", battery_volume);
		map.put("battery_voltage", battery_voltage);
		map.put("battery_charge_times", battery_charge_times);
		map.put("battery_voltage_max", battery_voltage_max);
		map.put("battery_current_max", battery_current_max);
		map.put("battery_energy_total", battery_energy_total);
		map.put("voltage_max", voltage_max);
		map.put("battery_temperature_max", battery_temperature_max);
		map.put("soc", soc);
		map.put("battery_voltage_total", battery_voltage_total);
        return map;
	}

	@Override
	public Map<String, String> summonReturnUploadTelemetry(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体
//		0x72	桩上传遥测数据
//		0x73	桩上传遥信数据
//		0x74	桩上传遥脉数据
		ev3c_frameCode ="72";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101SummonReturnUploadTelemetry(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101SummonReturnUploadTelemetry(Map<String, String> map) {
		String data = map.get("data");
		float thisVoltage = StringUtil.float16to10ByParamDesc(data.substring(50,56), 100); //*充电电压(V)系数为0.01:低字节在前，高字节在后，数据放大100倍，如0x1D 0x57 0x00,表示实际数据为223.01V
		float thisElectricity = StringUtil.float16to10ByParamDesc(data.substring(56, 62), 100); //电流与电压类似
		int this_hour = (int)StringUtil.float16to10ByParamDesc(data.substring(62, 68), 1);//充电时间
		int this_minute = (int)StringUtil.float16to10ByParamDesc(data.substring(68, 74), 1);//充电时间
		//*输出功率(W)	BIN码	3	系数为1	低字节在前，高字节在后，如 0x00 0xBC 0x1B,表示实际数据为 7100 W
		int this_power = (int)StringUtil.float16to10ByParamDesc(data.substring(74, 80), 1);//	
		map.put("thisVoltage", String.valueOf(thisVoltage));
		map.put("thisElectricity", String.valueOf(thisElectricity));
		map.put("this_hour", String.valueOf(this_hour));
		map.put("this_minute", String.valueOf(this_minute));
		map.put("this_power", String.valueOf(this_power));
		return map;
	}

	@Override
	public Map<String, String> summonReturnUploadTelesignal(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体
//		0x72	桩上传遥测数据
//		0x73	桩上传遥信数据
//		0x74	桩上传遥脉数据
		ev3c_frameCode ="73";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101SummonReturnUploadTelesignal(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101SummonReturnUploadTelesignal(Map<String, String> map) {
		String data = map.get("data");
		String charge_status =data.substring(50, 52);
		int charge_status_int = StringUtil.sixteen2tenInt(charge_status);
		String fault_status =data.substring(52, 54);
		int fault_status_int = StringUtil.sixteen2tenInt(fault_status);
		String bespeak_status =data.substring(54, 56);
		int bespeak_status_int = StringUtil.sixteen2tenInt(bespeak_status);
		String plug_status =data.substring(56, 58);
		int plug_status_int = StringUtil.sixteen2tenInt(plug_status);
		map.put("charge_status", String.valueOf(charge_status_int));
		map.put("fault_status", String.valueOf(fault_status_int));
		map.put("bespeak_status", String.valueOf(bespeak_status_int));
		map.put("plug_status", String.valueOf(plug_status_int));
		return map;
	}

	@Override
	public Map<String, String> summonReturnUploadPulse(Map<String, String> map) {
//		Map<String, String> map= StringUtil.string2JSONObject(str);
		//进一步解析  报文体
//		0x72	桩上传遥测数据
//		0x73	桩上传遥信数据
//		0x74	桩上传遥脉数据
		ev3c_frameCode ="74";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				map = ev3c0101SummonReturnUploadPulse(map);
				break;
			default:
				break;
		}
		return map;
	}

	private Map<String, String> ev3c0101SummonReturnUploadPulse(Map<String, String> map) {
		String data = map.get("data");
		float charge_quantity = StringUtil.float16to10ByParamDesc(data.substring(50,58), 100);
		float charge_amount = StringUtil.float16to10ByParamDesc(data.substring(58,64), 100);
		map.put("charge_quantity", String.valueOf(charge_quantity));
		map.put("charge_amount", String.valueOf(charge_amount));
		return map;
	}
	
	@Override
	public Map<String, String> chargerRegister(Map<String, String> map) {
		return null;
	}

	@Override
	public Map<String, String> chargerUnRegister(Map<String, String> map) {
		return null;
	}

	@Override
	public Map<String, String> chargerLogin(Map<String, String> map) {
		return null;
	}

	@Override
	public Map<String, String> chargerLogout(Map<String, String> map) {
		return null;
	}
}
